package com.lancoo.znbkxx.teacher.widget.voicePlayer;

import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnBufferingUpdateListener;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnPreparedListener;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.lifecycle.DefaultLifecycleObserver;
import androidx.lifecycle.LifecycleOwner;
import com.lancoo.znbkxx.teacher.R;
import com.lancoo.znbkxx.teacher.aibkTestCoach.aibkTools.MyToast;
import com.lancoo.znbkxx.teacher.utils.TimeUtils;
import com.lancoo.znbkxx.teacher.utils.ToastUtils;
import java.io.IOException;
import java.util.Timer;
import java.util.TimerTask;


public class VoicePlayer implements OnBufferingUpdateListener, OnCompletionListener,
		OnPreparedListener, DefaultLifecycleObserver, MediaPlayer.OnSeekCompleteListener, MediaPlayer.OnErrorListener {

	public MediaPlayer mediaPlayer; // 媒体播放器
	private final SeekBar seekBar; // 拖动条
	private final String musicUrl;
	private final TextView tv_time;
	private final ImageView ivPlay;
	private Timer mTimer ;
	private final String time;
	// 计时器
	private TimerTask timerTask;

	public boolean isPrepare() {
		return isPrepare;
	}

	public void setPrepare(boolean prepare) {
		isPrepare = prepare;
	}

	private boolean isPrepare = false;

	private boolean isSeek = true;//是否可以拖动
	private boolean isSeekBackStart = true;//是否在播放结束后重置播放进度

	private boolean isBtnPlayClickAble = false;
	public boolean getBtnPlayClickAble() {
		return isBtnPlayClickAble;
	}
	public void setBtnPlayClickAble(boolean btnPlayClickAble) {
		isBtnPlayClickAble = btnPlayClickAble;
	}

	private PlayListener playListener;
	// 初始化播放器
	public VoicePlayer(SeekBar seekBar, final String musicUrl, TextView tv_time, ImageView ivPlay, final boolean isBtnPlayClickAble,
					   boolean isSeek, boolean isSeekBackStart,final PlayListener playListener) {
		super();
		this.time = seekBar.getContext().getResources().getString(R.string.listen_voice);
		this.tv_time = tv_time;
		this.seekBar = seekBar;
		this.musicUrl = musicUrl;
		this.ivPlay = ivPlay;
		this.isBtnPlayClickAble = isBtnPlayClickAble;
		this.isSeek = isSeek;
		this.isSeekBackStart = isSeekBackStart;
		ivPlay.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				if(getBtnPlayClickAble()) {
					playListener.onStartPlay();
				}
			}
		});

		this.seekBar.setEnabled(false);
		new Thread(new Runnable() {
			@Override
			public void run() {
				playPrepareAsync(musicUrl);
			}
		}).start();

		this.playListener = playListener;

	}

	private void startTime(){
		if (mTimer == null){
			mTimer = new Timer();
		}
		if (timerTask  == null){
			timerTask = new TimerTask() {

				@Override
				public void run() {
					if (mediaPlayer == null)
						return;
					if (isPrepare && mediaPlayer.isPlaying() && !seekBar.isPressed()) {
						handler.sendEmptyMessage(0); // 发送消息
					}
				}
			};
			// 每一秒触发一次
			mTimer.schedule(timerTask, 0, 50);
		}
	}



	 private final Handler handler = new Handler() {
		public void handleMessage(android.os.Message msg) {
			if (mediaPlayer != null) { //避免出现空指针异常
				int position = mediaPlayer.getCurrentPosition();
				int duration = mediaPlayer.getDuration();
				String currentTimeStr = TimeUtils.getTimeType1FromMillis(position);
			switch (msg.what) {
				case 0:
						if (duration > 0) {
							// 计算进度（获取进度条最大刻度*当前音乐播放位置 / 当前音乐时长）
							long pos = seekBar.getMax() * position / duration;
							seekBar.setProgress((int) pos);
							tv_time.setText(String.format(time, currentTimeStr,
									TimeUtils.getTimeType1FromMillis(mediaPlayer.getDuration())));
						}

				break;
				case 1:
					MyToast.INSTANCE.showToast("音频地址出错，无法获取音频资源");
					break;
				case 2://隔1.5秒秒跳转到开始出 免得显示突兀
					seekBar.setProgress(0);
					String currentTimeStr1 = TimeUtils.getTimeType1FromMillis(0);
					tv_time.setText(String.format(time, currentTimeStr1,
							TimeUtils.getTimeType1FromMillis(mediaPlayer.getDuration())));
					ivPlay.setImageResource(R.mipmap.ic_music_play);
					break;
			}
			}
		}

	 };



	public void play() {
		if (isPrepare&&mediaPlayer!=null) {
			if (!mediaPlayer.isPlaying()) {
				mediaPlayer.start();
				ivPlay.setImageResource(R.mipmap.ic_music_pause);
			} else {
				pause();
			}
		}



	}

	public void rePlay(){
		mediaPlayer.seekTo(0);

		seekBar.setProgress(0);
		String currentTimeStr1 = TimeUtils.getTimeType1FromMillis(0);
		tv_time.setText(String.format(time, currentTimeStr1,
				TimeUtils.getTimeType1FromMillis(mediaPlayer.getDuration())));
		ivPlay.setImageResource(R.mipmap.ic_music_play);
	}

	// 暂停
	public void pause() {
		if (mediaPlayer != null && mediaPlayer.isPlaying()) {
			mediaPlayer.pause();
			new Thread(new Runnable() {
				@Override
				public void run() { //　新建一个线程，并新建一个Message的对象，是用Handler的对象发送这个Message
					Message msg = new Message();
					msg.what = 1; // 用户自定义的一个值，用于标识不同类型的消息
					hd.sendMessage(msg); // 发送消息
				}
			}).start();
		}
	}

	private Handler hd = new MyHandler();

	@Override
	public void onSeekComplete(MediaPlayer mp) {

	}

	@Override
	public boolean onError(MediaPlayer mp, int what, int extra) {
		mediaPlayer.release();
		mediaPlayer=null;
		return true;
	}

	// 定义一个内部类继承自Handler，并且覆盖handleMessage方法用于处理子线程传过来的消息
	class MyHandler extends Handler{
		@Override
		public void handleMessage(Message msg) {
			super.handleMessage(msg);
			switch (msg.what) {
				case 1: // 接受到消息之后，对UI控件进行修改
					ivPlay.setImageResource(R.mipmap.ic_music_play);
					break;

				default:
					break;
			}
		}
	}

	@Override
	public void onDestroy(@NonNull LifecycleOwner owner) {
		pause();
	}

	@Override
	public void onPause(@NonNull LifecycleOwner owner) {
		pause();
	}

	@Override
	public void onResume(@NonNull LifecycleOwner owner) {
		pause();
	}

	@Override
	public void onStop(@NonNull LifecycleOwner owner) {
		pause();
	}

	// 停止
	public void stop() {
		ivPlay.setImageResource(R.mipmap.ic_music_play);
		if(timerTask != null){
			timerTask.cancel();
			timerTask = null;
		}
		if (mTimer != null){
			mTimer.cancel();
			mTimer = null;
		}

		if (mediaPlayer != null) {
			mediaPlayer.stop();
			mediaPlayer.release();
			mediaPlayer = null;
		}
	}


	@Override
	public void onPrepared(MediaPlayer mp) {

		if(mediaPlayer!=null) {
			tv_time.setText(String.format(time, TimeUtils.getTimeType1FromMillis(0),
					TimeUtils.getTimeType1FromMillis(mediaPlayer.getDuration())));
			seekBar.setOnSeekBarChangeListener(new SeekBarChangeEvent());
			startTime();
		}

		ivPlay.setImageResource(R.mipmap.ic_music_play);
		isPrepare = true;
		setPrepare(true);
		seekBar.setEnabled(isSeek);
	}

	@Override
	public void onCompletion(MediaPlayer mp) {

		if(mediaPlayer!=null) {
			seekBar.setProgress(seekBar.getMax());
			tv_time.setText(String.format(time, TimeUtils.getTimeType1FromMillis(mediaPlayer.getDuration()),
					TimeUtils.getTimeType1FromMillis(mediaPlayer.getDuration())));
			if (isSeekBackStart) {
				handler.sendEmptyMessageDelayed(2, 1500);
			}
		}

		ivPlay.setImageResource(R.mipmap.ic_music_play);
		playListener.onFinishPlay();
	}

	public interface PlayListener{
		void onFinishPlay();
		void onStartPlay();
	}

	/**
	 * 缓冲更新
	 */
	@Override
	public void onBufferingUpdate(MediaPlayer mp, int percent) {
		seekBar.setSecondaryProgress(percent);
	}

    private class SeekBarChangeEvent implements SeekBar.OnSeekBarChangeListener{
        int progress;

        @Override
        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
            this.progress = progress * mediaPlayer.getDuration()
                    / seekBar.getMax();
        }

        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {

        }

        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {
            mediaPlayer.seekTo(progress);
        }
    }

    /***************************************************/
	public void playPrepareAsync(String musicUrl) {
		try {
			if (musicUrl == null) {
				return;
			}
			destoryMediaPlayer();
			mediaPlayer = new MediaPlayer();
			mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
			mediaPlayer.setOnCompletionListener(this);
			mediaPlayer.setOnPreparedListener(this);
			mediaPlayer.setOnSeekCompleteListener(this);
			mediaPlayer.setOnErrorListener(this);
			mediaPlayer.setOnBufferingUpdateListener(this);
			mediaPlayer.setDataSource(musicUrl);
			mediaPlayer.prepareAsync();

		} catch (IllegalArgumentException e) {
			e.printStackTrace();
			Log.e("playPrepareAsync", "IllegalArgumentException无法播放" + musicUrl);
		} catch (IOException e) {
			Log.e("playPrepareAsync", "IOException无法播放" + musicUrl);
			e.printStackTrace();
		} catch (Exception e) {
			Log.e("playPrepareAsync", "Exception无法播放" + musicUrl);
		}
	}

	public void destoryMediaPlayer() {
		try {
			if (mediaPlayer != null) {
				mediaPlayer.setOnCompletionListener(null);
				mediaPlayer.setOnPreparedListener(null);
				mediaPlayer.reset();
				mediaPlayer.release();
				mediaPlayer = null;
			}
		} catch (Exception e) {
		}
	}


}
